// use rand::Rng;

use std::io::Error;
use std::{fs::File, io::Read};

use crate::handler::{Response, UserInfo}; // err code
pub enum Code {
    ErrDatabase,
    IsOk,
    ErrValidation,
    ErrUserNotFound,
    ErrEncrypt,
    ErrToken,
    InternalServerError,
}

pub enum Message {
    msg,
    msgAdd(String),
}

pub fn decode_err2(data: Message) -> (i32, String) {
    match data {
        Message::msg => (0, "ok".to_string()),
        Message::msgAdd(i) => (400, format!("hello {}", i)),
    }
}

pub fn demo0() {
    let (code, str) = decode_err2(Message::msg);
    println!("code 1 => {}", code);
    println!("str 1 => {}", str);

    let (code1, str1) = decode_err2(Message::msgAdd("word".to_string()));
    println!("code 1 => {}", code1);
    println!("str 1 => {}", str1);
}

pub fn decode_err(code: Code) -> (i32, &'static str) {
    match code {
        Code::ErrDatabase => (0, "sql err."),
        Code::IsOk => (2000, "ok"),
        Code::ErrValidation => (2001, "validation err."),
        Code::ErrEncrypt => (2002, "encrypt."),
        Code::ErrToken => (2003, "token err."),
        Code::ErrUserNotFound => (3001, "user not found."),
        Code::InternalServerError => (5000, "server err."),
    }
}

pub fn send_response<'a, T>(code: Code, data: Option<T>) -> super::Response<'a, T> {
    let (code, message) = decode_err(code);
    let res = super::Response {
        code,
        message,
        data,
    };
    res
}

pub fn demo1() {
    let name = send_response(Code::IsOk, Some("zds"));
    println!("name {:#?}", name);
    println!("name code {}", name.code);

    let no_sql: Response<'_, ()> = send_response(Code::ErrDatabase, None);
    println!("no_sql {:#?}", no_sql);
    println!("no_sql {}", no_sql.code);

    let user_info = send_response(
        Code::IsOk,
        Some(UserInfo {
            id: 1,
            name: "zds",
            age: 18,
        }),
    );
    println!("info {:#?}", user_info);
    println!("info {:#?}", user_info);
}

pub async fn is_null(num: i32) -> Option<bool> {
    if num > 3 {
        Some(true)
    } else {
        None
    }
}

pub async fn is_err(name: &str) -> Result<(), &str> {
    if name == "zds" {
        Ok(())
    } else {
        Err("no found name.")
    }
}

pub async fn open_file(path: &str) -> Result<File, Error> {
    let file = File::open(path)?;
    Ok(file)
}

pub async fn demo2(num: i32) {
    let cont = is_null(num).await;
    match cont {
        Some(i) => println!("cont {}", i),
        None => println!("cont is null."),
    }
}

pub async fn demo3(name: &str) {
    let res = is_err(name).await;
    match res {
        Ok(()) => println!("name is ok"),
        Err(i) => println!("{}", i),
    }
}

pub async fn demo3_file(file_path: &str) {
    let res = open_file(file_path).await;
    match res {
        Ok(mut file) => {
            let mut text = String::new();
            match file.read_to_string(&mut text) {
                Ok(_) => println!("read text: {}", text),
                Err(e) => println!("read err {}", e),
            }
        }
        Err(e) => println!("file err {:#?}", e),
    }
}
